package com.org.utils.conf;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.*;

/**
 * Properties文件模式Configure
 * 
 * @author 
 * @date 2011.12.30
 */
public class ConfigureProperties extends BaseConfigure implements Configure {

	/**
	 * 构造器
	 * 
	 * @param fileName
	 * @param encoding
	 * @throws IOException
	 */
	public ConfigureProperties(String fileName, String encoding)
			throws IOException {
		super(fileName, encoding);
	}

	/**
	 * 获取配置项目值
	 * 
	 * 
	 * 
	 */
	public synchronized String getProperty(String name) throws IOException {
		String result = "";
		String property = (String) propertyCache.get(name); // 直接从缓存中获取属性
		if (property != null)
			result = ConfigureMacro.getRealValue(property);
		else {
			loadProps(); // 加载所有属性值到缓存
			property = (String) propertyCache.get(name);
			if (property == null) {
				log.warn("Cannot find property: " + name);
				return null;
			} else {
				result = ConfigureMacro.getRealValue(property.trim());
			}
		}
		return result;
	}

	/**
	 * 获取所有配置项值
	 * 
	 */
	public String[] getAllProperty() throws IOException {
		String result[] = null;
		List<String> matchPropNames = new ArrayList<String>(5);
		if (propertyCache == null)
			loadProps();
		if (propertyCache.size() == 0)
			loadProps(); // 加载所有属性值到缓存
		Iterator<Object> iterator = propertyCache.keySet().iterator();
		Iterator<Object> propertyNames = iterator;
		while (propertyNames.hasNext()) {
			String propName = (String) propertyNames.next();
			matchPropNames.add(propName);
		}
		result = matchPropNames.toArray(new String[0]);
		return result;
	}

	/**
	 * 获取子配置项目对象
	 * 
	 */
	public synchronized String[] getChildrenPropertyNames(
			String parentPropertyName) throws IOException {
		String result[] = null;
		String propName = null;
		List<String> matchPropNames = new ArrayList<String>(5);
		if (propertyCache == null)
			loadProps();
		Iterator<Object> propertyNames = propertyCache.keySet().iterator();
		while (propertyNames.hasNext()) {
			propName = (String) propertyNames.next();
			if (propName.startsWith(parentPropertyName))
				matchPropNames.add(propName);
		}
		result = matchPropNames.toArray(new String[0]);
		return result;
	}

	/**
	 * 设置一个配置项目
	 * 
	 */
	public synchronized void setProperty(String name, String value)
			throws IOException {
		OutputStream out = null;
		OutputStreamWriter osw = null;
		InputStream in = null;
		InputStreamReader isr = null;
		BufferedReader br = null;
		boolean isNewProp = false;
		String line = "";
		String content = "";
		String key = null;
		try {
			if (propertyCache == null)
				loadProps();
			if (!propertyCache.containsKey(name))
				isNewProp = true;
			propertyCache.put(name, value); // 设置Configure中缓存的属性
			if (!isNewProp) { // 如果存在此属性,则修改属性值
				in = new FileInputStream(configureFileName);
				isr = new InputStreamReader(in, encoding);
				br = new BufferedReader(isr);
				while (null != (line = br.readLine())) {
					int idx = -1;
					line = line.trim();
					if (-1 == (idx = line.indexOf("="))) {
						content = content + line + "\n";
					} else {
						key = line.substring(0, idx).trim();
						if (!key.equals(name))
							content = content + line + "\n";
						else
							content = content + key + " = " + value + "\n";
					}
				}
				out = new FileOutputStream(configureFileName, false);
				osw = new OutputStreamWriter(out, encoding);
				osw.write(content);
			} else { // 如果不存在此属性,追加属性
				out = new FileOutputStream(configureFileName, true);
				osw = new OutputStreamWriter(out, encoding);
				osw.write("\n" + name + " = " + value + "\n");
			}
		} finally {
			if (osw != null)
				osw.close();
			if (out != null)
				out.close();
			if (br != null)
				br.close();
			if (isr != null)
				isr.close();
			if (in != null)
				in.close();

		}
	}

	/**
	 * 删除一个配置项目
	 * 
	 */
	public synchronized void deleteProperty(String name) throws IOException {
		OutputStream out = null;
		OutputStreamWriter osw = null;
		InputStream in = null;
		InputStreamReader isr = null;
		BufferedReader br = null;
		String line = "";
		String content = "";
		String key = null;
		try {
			if (propertyCache == null)
				loadProps();
			in = new FileInputStream(configureFileName);
			isr = new InputStreamReader(in, encoding);
			br = new BufferedReader(isr);
			do {
				if (null == (line = br.readLine())) // 空行,结束
					break;
				int idx = -1;
				line = line.trim();
				if (-1 == (idx = line.indexOf("="))) {
					content = content + line + "\n";
				} else { // 清除属性
					key = line.substring(0, idx).trim();
					if (!key.equals(name))
						content = content + line + "\n";
				}
			} while (true);
			out = new FileOutputStream(configureFileName, false);
			osw = new OutputStreamWriter(out, encoding);
			osw.write(content);
			propertyCache.remove(name); // 清除Configure中缓存的属性
		} finally {
			if (osw != null)
				osw.close();
			if (out != null)
				out.close();
			if (br != null)
				br.close();
			if (isr != null)
				isr.close();
			if (in != null)
				in.close();
		}
	}

	/**
	 * 从文件加载所有配置项目Configure的缓存
	 * 
	 * @throws IOException
	 */
	private synchronized void loadProps() throws IOException {
		Hashtable<Object, Object> properties = new Hashtable<Object, Object>();
		InputStream in = null;
		InputStreamReader isr = null;
		BufferedReader br = null;
		String line = null;
		int idx = -1;
		String key = null;
		String value = null;
		try {
			in = new FileInputStream(configureFileName);
			isr = new InputStreamReader(in, encoding);
			br = new BufferedReader(isr);
			do {
				if (null == (line = br.readLine())) // 空行,结束
					break;
				line = line.trim(); // 不为"#"注释和有"="才加载属性项
				if (!line.startsWith("#") && -1 != (idx = line.indexOf("="))) {
					key = line.substring(0, idx).trim();
					value = line.substring(idx + 1).trim();
					properties.put(key, value);
				}
			} while (true);
			propertyCache = properties;
		} finally {
			try {
				if (br != null)
					br.close();
				if (isr != null)
					isr.close();
				if (in != null)
					in.close();
			} catch (Exception e) {
				log.error("从文件读取加载属性配置失败" + e.getMessage());
			}
		}
	}
}
